package solutions.ferpa.ztest.ent;

import java.sql.*;
import java.util.ArrayList;
import br.com.telescope.adsrt.dom.*;
import br.com.telescope.adsrt.lib.*;
import java.util.Random;
import br.com.telescope.t2.exception.Severity;

/**
 * API de persistência de dados da entidade SEQUENCE_NUMBERS
 * @author Gerado pelo Telescope
 */
public class EntSequenceNumbers extends Entity {
    
    public final static String ENTITY_NAME = "SEQUENCE.SEQUENCE_NUMBERS";
    public final static String TABLE_NAME = "SEQUENCE_NUMBERS";
    // <user-code id="11636355" parentId="11636354" hashcode="57219daa" length="205">
    // import java.util.Random;
    private static Random random;
    private Random getRandom() {
        if (random == null) {
            random = new Random(System.currentTimeMillis());
        }
        return random;
    }
    
    // </user-code>
    
    // <editor-fold defaultstate="collapsed" desc="Contrutores e inicializacao">
    /**
     * Construtores
     */
    public EntSequenceNumbers() {
        super();
        initialize();
    }
    
    public EntSequenceNumbers(BaseRuntime ctx) {
        super();
        initialize(ctx);
    }
    
    @Override
    public String getPrimaryKeyColumn() {
        return "ID";
    }
    
    @Override
    public void initialize(BaseRuntime ctx) {
        super.initialize(ctx);
        initialize();
    }
    
    public void initialize() {
        aId = new DomId(this,"ID", "Id"); 
        aId.setRequired(true);
        oId = new DomId();
        aSequenceId = new DomId(this,"SEQUENCE_ID", "Sequence"); 
        aSequenceId.setRequired(true);
        oSequenceId = new DomId();
        aNumber = new DomBigInteger(this,"NUMBER", "Number"); 
        aNumber.setRequired(true);
        oNumber = new DomBigInteger();
        aOrdering = new DomBigInteger(this,"ORDERING", "Order"); 
        aOrdering.setRequired(true);
        oOrdering = new DomBigInteger();
        aConsumed = new DomFlag(this,"CONSUMED", "Consumed"); 
        aConsumed.setRequired(true);
        aConsumed.setSize(1);
        aConsumed.setDefaultValue("N");
        oConsumed = new DomFlag();
        ressetModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributos da entidade">
    
    // Id
    private DomId aId;
    private DomId oId;
    
    // Sequence
    private DomId aSequenceId;
    private DomId oSequenceId;
    
    // Number
    private DomBigInteger aNumber;
    private DomBigInteger oNumber;
    
    // Order
    private DomBigInteger aOrdering;
    private DomBigInteger oOrdering;
    
    // Consumed
    private DomFlag aConsumed;
    private DomFlag oConsumed;
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ID">
    
    public EntSequenceNumbers id(Long value) {
        setId(value);
        return this;
    }
    
    public void setId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyId();
        } else {
            aId.setValue(value.getValue());
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(String value) {
        if (value == null) {
            nullifyId();
        } else {
            aId.setValue(value);
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(Long value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void setId(Object value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyId() {
        if (!aId.isNull()) {
            aId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getId() {
        return aId;
    }
    
    public DomId oldId() {
        return oId;
    }
    
    public Long valueOfId() {
        return aId.getValue();
    }
    
    public boolean isIdModified() {
        return aId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo SEQUENCE_ID">
    
    public EntSequenceNumbers sequenceId(Long value) {
        setSequenceId(value);
        return this;
    }
    
    public void setSequenceId(DomId value) {
        if (value == null || value.isNull()) {
            nullifySequenceId();
        } else {
            aSequenceId.setValue(value.getValue());
            if (aSequenceId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setSequenceId(String value) {
        if (value == null) {
            nullifySequenceId();
        } else {
            aSequenceId.setValue(value);
            if (aSequenceId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setSequenceId(Long value) {
        aSequenceId.setValue(value);
        if (aSequenceId.isModified()) {
            setModified(true);
        }
    }
    
    public void setSequenceId(Object value) {
        aSequenceId.setValue(value);
        if (aSequenceId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifySequenceId() {
        if (!aSequenceId.isNull()) {
            aSequenceId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getSequenceId() {
        return aSequenceId;
    }
    
    public DomId oldSequenceId() {
        return oSequenceId;
    }
    
    public Long valueOfSequenceId() {
        return aSequenceId.getValue();
    }
    
    public boolean isSequenceIdModified() {
        return aSequenceId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo NUMBER">
    
    public EntSequenceNumbers number(Long value) {
        setNumber(value);
        return this;
    }
    
    public void setNumber(DomBigInteger value) {
        if (value == null || value.isNull()) {
            nullifyNumber();
        } else {
            aNumber.setValue(value.getValue());
            if (aNumber.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setNumber(String value) {
        if (value == null) {
            nullifyNumber();
        } else {
            aNumber.setValue(value);
            if (aNumber.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setNumber(Long value) {
        aNumber.setValue(value);
        if (aNumber.isModified()) {
            setModified(true);
        }
    }
    
    public void setNumber(Object value) {
        aNumber.setValue(value);
        if (aNumber.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyNumber() {
        if (!aNumber.isNull()) {
            aNumber.setNull(true);
            setModified(true);
        }
    }
    
    public DomBigInteger getNumber() {
        return aNumber;
    }
    
    public DomBigInteger oldNumber() {
        return oNumber;
    }
    
    public Long valueOfNumber() {
        return aNumber.getValue();
    }
    
    public boolean isNumberModified() {
        return aNumber.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ORDERING">
    
    public EntSequenceNumbers ordering(Long value) {
        setOrdering(value);
        return this;
    }
    
    public void setOrdering(DomBigInteger value) {
        if (value == null || value.isNull()) {
            nullifyOrdering();
        } else {
            aOrdering.setValue(value.getValue());
            if (aOrdering.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setOrdering(String value) {
        if (value == null) {
            nullifyOrdering();
        } else {
            aOrdering.setValue(value);
            if (aOrdering.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setOrdering(Long value) {
        aOrdering.setValue(value);
        if (aOrdering.isModified()) {
            setModified(true);
        }
    }
    
    public void setOrdering(Object value) {
        aOrdering.setValue(value);
        if (aOrdering.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyOrdering() {
        if (!aOrdering.isNull()) {
            aOrdering.setNull(true);
            setModified(true);
        }
    }
    
    public DomBigInteger getOrdering() {
        return aOrdering;
    }
    
    public DomBigInteger oldOrdering() {
        return oOrdering;
    }
    
    public Long valueOfOrdering() {
        return aOrdering.getValue();
    }
    
    public boolean isOrderingModified() {
        return aOrdering.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo CONSUMED">
    
    public EntSequenceNumbers consumed(String value) {
        setConsumed(value);
        return this;
    }
    
    public void setConsumed(DomFlag value) {
        if (value == null || value.isNull()) {
            nullifyConsumed();
        } else {
            aConsumed.setValue(value.getValue());
            if (aConsumed.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setConsumed(String value) {
        if (value == null) {
            nullifyConsumed();
        } else {
            aConsumed.setValue(value);
            if (aConsumed.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setConsumed(Object value) {
        aConsumed.setValue(value);
        if (aConsumed.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyConsumed() {
        if (!aConsumed.isNull()) {
            aConsumed.setNull(true);
            setModified(true);
        }
    }
    
    public DomFlag getConsumed() {
        return aConsumed;
    }
    
    public DomFlag oldConsumed() {
        return oConsumed;
    }
    
    public String valueOfConsumed() {
        return aConsumed.getValue();
    }
    
    public boolean isConsumedModified() {
        return aConsumed.isModified();
    }
    // </editor-fold>
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="getErrors">
    /**
     * Traduz um erro recebido do banco de dados para um AdsException
     */
    @Override
    public AdsException getErrors(String errorMsg, int transaction) {
        AdsException e;
        String msg = errorMsg.toUpperCase();
        
        if (transaction == DELETE_TRANSACTION) {
            e = new AdsException("SEQUENCE.SEQUENCE_NUMBERS.GET_ERRORS_UNKNOWN",
                    AdsException.UNKNOWN,
                    "Erro não esperado: " + errorMsg);
        } else {
            if (msg.indexOf("PK_SEQNUM") >= 0) {
                e = new AdsException("SEQUENCE.SEQUENCE_NUMBERS.PK_SEQNUM", 
                        Severity.ERROR,
                        "ID duplicado! (PK_SEQNUM)");
                return e;
            } else if (msg.indexOf("FK_SEQNUM_SEQUENCE") >= 0) {
                e = new AdsException("SEQUENCE.SEQUENCE_NUMBERS.FK_SEQNUM_SEQUENCE", 
                        Severity.ERROR,
                        "Registro não cadastrado para SEQUENCE! (FK_SEQNUM_SEQUENCE)");
                return e;
            } else {
                e = new AdsException("SEQUENCE.SEQUENCE_NUMBERS.GET_ERRORS_UNKNOWN",
                        AdsException.UNKNOWN,
                        "Erro não esperado: " + errorMsg);
            }
        }
        return e;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Entity Information">
    
    public String getEntityName() {
        return ENTITY_NAME;
    }
    
    public String getTableName() {
        return TABLE_NAME;
    }
    
    public String idSequenceName() {
        return "PK_SEQUENCE";
    }
    
    private ArrayList<Field> allAttributes;
    public ArrayList<Field> getAllAttributes() {
        if (allAttributes == null) {
            allAttributes = new ArrayList<Field>();
            allAttributes.add(aId);
            allAttributes.add(aSequenceId);
            allAttributes.add(aNumber);
            allAttributes.add(aOrdering);
            allAttributes.add(aConsumed);
        }
        return allAttributes;
    }
    
    /**
     * Retorna o valor da primeira UK da entidade
     * Se ela for composta, retorna a concatenação de toda a combinação
     * de atributos separados por um espaço.
     */
    public String valueOfUk() {
        return "";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Relationships">
    
    
    private EntSequences eSequence;
    
    public EntSequences findSequence() throws AdsException {
        if (getSequenceId().isNull()) {
            return null;
        }
        if (eSequence == null || !valueOfSequenceId().equals(eSequence.valueOfId())) {
            eSequence = new EntSequences(ctx);
            eSequence.find(valueOfSequenceId());
        }
        return eSequence;
    }
    
    /**
     * Ativa o join desta entidade com SEQUENCES
     * através do atributo SEQUENCE_ID
     */
    public EntSequences joinSequence() {
        return joinSequence(null);
    }
    public EntSequences joinSequence(String alias) {
        EntSequences entity = new EntSequences(ctx);
        if (alias != null) {
            entity.setAlias(alias);
        }
        Join newJoin = new Join(getSequenceId(), entity);
        entity.setJoinedBy(newJoin);
        this.join(newJoin);
        return entity;
    }
    
    public void findBySequence(long id, String sqlAppend) throws AdsException {
        find("select ID from SEQUENCE_NUMBERS where SEQUENCE_ID = ? " + sqlAppend);
        sqlSetLong(1,id);
    }
    
    public void findBySequence(long id) throws AdsException {
        findBySequence(id,"");
    }
    
    public void findBySequence(Entity entidade) throws AdsException {
        findBySequence(entidade.valueOfId(),"");
    }
    
    public void findBySequence(Entity entidade, String sqlAppend) throws AdsException {
        findBySequence(entidade.valueOfId(),sqlAppend);
    }
    
    /**
     * Limpa os objetos normalizados da entidade
     */
    public void clearRelatedObjects() {
        eSequence = null;
    }
    
    /**
     * Método que copia os valores dos atributos
     * para os valores respectivos old 
     */
    public void saveOldAtributes() {
        oId.setValue(aId);
        oNumber.setValue(aNumber);
        oSequenceId.setValue(aSequenceId);
        oOrdering.setValue(aOrdering);
        oConsumed.setValue(aConsumed);
    }
    
    /**
     * Método que retorna as regras da entidade
     * @return ArrayList com as regras ou null caso não existir nenhuma regra
     */
    public ArrayList getAllRules() {
        ArrayList<EntityRule> out = new ArrayList<EntityRule>();
        {
            PrimaryKeyRule rule = new PrimaryKeyRule();
            rule.setEntity(EntSequenceNumbers.class);
            rule.setName("PK_SEQNUM");
            rule.setPkAttribute(new DomId("ID",""));
            out.add(rule);
        }
        {
            ForeignKeyRule rule = new ForeignKeyRule();
            rule.setEntity(EntSequenceNumbers.class);
            rule.setAssociatedEntity(EntSequences.class);
            rule.setName("FK_SEQNUM_SEQUENCE");
            rule.addAttribute(new DomId("SEQUENCE_ID",""));
            out.add(rule);
        }
        return out;
    }
    // </editor-fold>
    
    @Override
    protected void preInsert() throws AdsException {
        criarOrdemAleatoria(); //Criar ordem aleatória
    }
    
    @Override
    public void fillDefaultValues() throws AdsException {
        if (aId.isNull()) {
            aId.setValue("" + ctx.getNextVal("pk_sequence"));
        }
        if (getConsumed().isNull()) {
            setConsumed(getConsumed().getDefaultValue());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Métodos customizados">
    
    /**
     * Regra de ação: Criar ordem aleatória
     * 
     * Prepara a ordem com que o número será consumido de forma aleatória.
     */
    private void criarOrdemAleatoria() throws AdsException {
        // <user-code id="11636353" parentId="11636349" hashcode="-73e98df8" length="36">
        setOrdering(getRandom().nextLong());
        // </user-code>
    }
}
